<template>
    <div id="mapBoxId"></div>
    <div class="option-btn__list">
        <button class="btn-item" @click="startMeasure">开始绘面</button>
        <button class="btn-item" @click="clearMeasure">清除</button>
    </div>
</template>
<script lang="ts" setup>
import { TDMAP_TK } from '@/utils/constant';
import { Overlay, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import { fromLonLat } from 'ol/proj';
import { XYZ } from 'ol/source';
import MapType from 'ol/Map.js';
import { defaults as defaultControls } from 'ol/control';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Fill from 'ol/style/Fill';
import Style from 'ol/style/Style';
import Stroke from 'ol/style/Stroke';
import Circle from 'ol/style/Circle';
import Draw from 'ol/interaction/Draw';
import { unByKey } from 'ol/Observable';
let map: MapType;
let drawLayers: any[] = [];
/**
 * The help tooltip element.
 * @type {HTMLElement}
 */
let helpTooltipElement: HTMLElement;

/**
 * Overlay to show the help messages.
 * @type {Overlay}
 */
let helpTooltip: Overlay;
let mapMouseMove: any;
let feature: any;
let draw: Draw;
let drawElements: any[] = [];

/**
 * 图层
 */
const getLayers = () => {
    // 天地图矢量图层
    const tdMapVectorLayer = new TileLayer({
        zIndex: 30,
        className: 'tdVector',
        visible: true,
        source: new XYZ({
            url: `https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${TDMAP_TK}`,
            wrapX: false
        })
    });
    // 天地图标注层
    const tdMapCvaLayer = new TileLayer({
        zIndex: 31,
        className: 'tdCva',
        visible: true,
        source: new XYZ({
            url: `https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=${TDMAP_TK}`,
            wrapX: false
        })
    });
    const layers = [tdMapVectorLayer, tdMapCvaLayer];
    return layers;
};
/**
 * 初始化地图
 */
const initMap = () => {
    const layers = getLayers();
    const view = new View({
        center: fromLonLat([86.25903, 41.33632]),
        zoom: 16,
        minZoom: 9,
        maxZoom: 18,
        constrainResolution: true, // 设置缩放级别为整数
        smoothResolutionConstraint: false // 关闭无级缩放地图
    });
    map = new MapType({
        target: 'mapBoxId',
        layers,
        view,
        controls: defaultControls({
            zoom: false,
            rotate: false,
            attribution: false
        })
    });
};
/**
 * 开始测距
 */
const startMeasure = () => {
    map.getInteractions().item(1).setActive(false);
    // 设置测距的图层
    const source = new VectorSource();
    const layer = new VectorLayer({
        source: source,
        style: new Style({
            fill: new Fill({
                //填充颜色
                color: 'rgba(37,241,239,0.2)'
            }),
            stroke: new Stroke({
                color: '#FF0000',
                width: 4
            }),

            image: new Circle({
                radius: 5,
                stroke: new Stroke({
                    color: '#FF0000', //边框颜色
                    width: 3
                }),
                fill: new Fill({
                    color: '#ffffff' //填充颜色
                })
            })
        }),
        zIndex: 32
    });
    mapMouseMove = map.on('pointermove', ev => {
        if (ev.dragging) {
            return;
        }
        let helpMsg = '单击开始';
        if (feature) {
            helpMsg = '双击结束';
        }
        helpTooltipElement.innerHTML = helpMsg;
        helpTooltip?.setPosition(ev.coordinate);
        helpTooltipElement.classList.remove('hidden');
    });

    map.getViewport().addEventListener('mouseout', function () {
        helpTooltipElement.classList.add('hidden');
    });

    draw = new Draw({
        source,
        type: 'Polygon',
        freehand:true,
        style: new Style({
            //图层样式
            fill: new Fill({
                //填充颜色
                color: 'rgba(37,241,239,0.2)'
            }),
            stroke: new Stroke({
                color: '#FF0000', //边框颜色
                width: 3, // 边框宽度
            }),
            image: new Circle({
                radius: 5,
                stroke: new Stroke({
                    color: '#FF0000', //边框颜色
                    width: 3
                }),
                fill: new Fill({
                    color: '#ffffff' //填充颜色
                })
            })
        })
    });


    // 双击绘制完成
    draw.on('drawend', () => {
        endMeasure();
    });
    createHelpTooltip();

    map.addLayer(layer);
    drawLayers.push(layer);
    map.addInteraction(draw);
};

/**
 * 提示框
 */
const createHelpTooltip = () => {
    if (helpTooltipElement) {
        helpTooltipElement.parentNode?.removeChild(helpTooltipElement);
    }
    helpTooltipElement = document.createElement('div');
    helpTooltipElement.className = 'ol-tooltip hidden';
    helpTooltip = new Overlay({
        element: helpTooltipElement,
        offset: [15, 0],
        positioning: 'center-left'
    });
    drawElements = drawElements || [];
    drawElements.push(helpTooltip);
    map.addOverlay(helpTooltip);
};
const endMeasure = () => {
    map.removeOverlay(helpTooltip);
    map.removeInteraction(draw);
};
/**
 * 清除测距组件
 */
const clearMeasure = () => {
    for (let i = 0; i < drawLayers.length; i++) {
        map.removeLayer(drawLayers[i]);
    }
    for (let i = 0; i < drawElements.length; i++) {
        map.removeOverlay(drawElements[i]);
    }
    drawLayers = [];
    drawElements = [];
    // map.removeOverlay(measureTooltip)
    map.removeInteraction(draw);
    unByKey(mapMouseMove);
};
/**
 * 销毁左侧地图
 */
const distoryMap = () => {
    map && map.setTarget();
    map && map.dispose();
};
onMounted(() => {
    initMap();
});
onBeforeUnmount(() => {
    distoryMap();
});
</script>
<style lang="scss" scoped>
#mapBoxId {
    width: 100vw;
    height: 100vh;
}
.option-btn__list {
    position: fixed;
    right: 20px;
    top: 20px;
    display: flex;
    z-index: 99;
    gap: 10px;
    .btn-item {
        border: none;
        background-color: #1e71ff;
        border-radius: 20px;
        padding: 0 20px;
        text-align: center;
        color: #fff;
        height: 36px;
        line-height: 36px;
        cursor: pointer;
    }
}
:deep(.ol-tooltip) {
    position: relative;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    color: white;
    padding: 4px 8px;
    opacity: 0.7;
    white-space: nowrap;
    font-size: 12px;
    cursor: default;
    user-select: none;
}

:deep(.ol-tooltip-measure) {
    opacity: 1;
    font-weight: bold;
}

:deep(.ol-tooltip-static) {
    background-color: #3352ff;
    color: black;
    border: 1px solid white;
    color: #fff;
}

:deep(.ol-tooltip-measure),
:deep(.ol-tooltip-static) {
    &::before {
        border-top: 6px solid rgba(0, 0, 0, 0.5);
        border-right: 6px solid transparent;
        border-left: 6px solid transparent;
        content: '';
        position: absolute;
        bottom: -6px;
        margin-left: -7px;
        left: 50%;
    }
}

:deep(.ol-tooltip-static::before) {
    border-top-color: #3352ff;
}
</style>
